package com.rizzo.analytics.services.repo;

import com.rizzo.analytics.domain.account.Account_;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.ListAttribute;
import javax.persistence.metamodel.SingularAttribute;

public class AccountSpecs<Account> extends EntitySpecs {

	@Override
	public Specification hasMoreChildrenThan(final long childCount) {
		return new Specification<Account>() {
			@Override
			public Predicate toPredicate(Root<Account> accountRoot, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
				return createHasMoreChildrenThanPredicate(accountRoot, criteriaQuery, criteriaBuilder, Account_.id, Account_.triggers, childCount);
			}
		};
	}

	@Override
	public Specification hasChildrenWithProperty(final ListAttribute joinProperty, final SingularAttribute childProperty, final Object childPropertyValue) {
		return new Specification<Account>() {
			@Override
			public Predicate toPredicate(Root<Account> accountRoot, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
				return createHasChildrenWithPropertyPredicate(accountRoot, criteriaQuery, criteriaBuilder, joinProperty, childProperty, childPropertyValue);
			}
		};
	}

	@Override
	public Specification fallsInPeriod(final DateTime startDate, final Period period) {
		return new Specification<Account>() {
			@Override
			public Predicate toPredicate(Root<Account> accountRoot, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
				return fallsInPeriodPredicate(accountRoot, criteriaQuery, criteriaBuilder, Account_.lastLogin, startDate, period);
			}
		};
	}

	@Override
	public Specification fallsInFuture() {
		return new Specification<Account>() {
			@Override
			public Predicate toPredicate(Root<Account> accountRoot, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
				return fallsInFuturePredicate(accountRoot, criteriaQuery, criteriaBuilder, Account_.lastLogin);
			}
		};
	}

	@Override
	public Specification fallsInPast() {
		return new Specification<Account>() {
			@Override
			public Predicate toPredicate(Root<Account> accountRoot, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
				return fallsInPastPredicate(accountRoot, criteriaQuery, criteriaBuilder, Account_.lastLogin);
			}
		};
	}

}
